﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SnelsteRoute
{
    public class Aspect
    {
        public static String[] PrimaryAspectNames = new string[] { "Aer","Aqua","Ignis","Ordo","Perditio","Terra" };

        public String Name { get; private set; }

        public String ImageUri { get{ return "img/" + Name+ ".png";}  private set{} }

        public List<Aspect> DerivedAspects { get; private set; }
        public List<Aspect> ChildAspects { get; private set; }

        private String[] _childAspectNames;

        private Int32 _cost = -1;
        public Int32 Cost
        {
            get
            {
                if (_cost < 0)
                    _cost = DetermineCost(this);

                return _cost;
            }
        }

        private static int DetermineCost(Aspect aspect)
        {
            if (aspect == null) return 0;
            if (aspect.ChildAspects.Count == 0) return 1;
            else
            {
                var totalCost = 0;
                foreach (var childAspect in aspect.ChildAspects)
                    totalCost += childAspect.Cost;

                return totalCost;
            }
        }

        public Aspect(String name, String[] childAspectNames)
        {
            Name = name;
            _childAspectNames = childAspectNames;

            ChildAspects = new List<Aspect>();
            DerivedAspects = new List<Aspect>();
        }

        internal void ResolveRelations(Configuration configuration)
        {
            foreach (var childAspectName in _childAspectNames)
            {
                var found = configuration.Aspects.FirstOrDefault(a => a.Name.Equals(childAspectName));

                if (found == null)
                    throw new Exception(String.Format("Aspect {0} is buildup from {1}, however this aspect cannot be found. typing error ?", Name, childAspectName));

                // some aspects are made up out of twice the same element, dont add it twice
                if (!ChildAspects.Contains(found))
                    ChildAspects.Add(found);
            }
        }

        internal void ResolveParentRelations(Configuration configuration)
        {
            foreach (var aspect in configuration.Aspects)
            {
                foreach (var childAspect in aspect.ChildAspects)
                {
                    if (childAspect.Name.Equals(this.Name))
                        DerivedAspects.Add(aspect);
                }
            }
        }

        internal bool Validate()
        {
            if (_childAspectNames.Length < 2)
            {
                if (_childAspectNames.Length == 1)
                {
                    throw new Exception("Aspect must be made out of two aspects " + ToString());
                }
                else
                {
                    // nr of aspects = 0
                    if (!PrimaryAspectNames.Contains(Name))
                        throw new Exception("Aspect is not made up of any other aspects, and is not a primary aspect " +  ToString());
                }
            }

            return true;
        }

        public override string ToString()
        {
            return String.Format("Name {0}, Provided aspectNames ({1}), found aspectNames ({2})",
                Name, 
                String.Join(",",_childAspectNames),
                String.Join(",",ChildAspects.Select(a => a.Name).ToArray()));
        }

    }
}
